package com.qinge.blog.utils.mybatis.interceptor;

import com.qinge.blog.utils.mybatis.CreateTime;
import com.qinge.blog.utils.mybatis.UpdateTime;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @author QDW
 * @date 2022/5/7 16:32
 * @description 创建时间
 **/
@Component
@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
public class CreateTimeInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];

        // 获取 SQL 命令
        SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();

        // 获取参数
        Object parameter = invocation.getArgs()[1];

        Field[] declaredFields=null;
        List<Field[]> allFieldList=null;

        // ParamMap
        if(parameter instanceof MapperMethod.ParamMap){
            MapperMethod.ParamMap<?> p = (MapperMethod.ParamMap<?>) parameter;
            if (p.containsKey("et")) {
                parameter = p.get("et");
                declaredFields = FieldUtil.getAllFields(parameter);
            }else if(p.containsKey("param1")){
                parameter = p.get("param1");
                declaredFields =  FieldUtil.getAllFields(parameter);
            }else{
                // 批量处理？
                parameter = p.get("list");
                allFieldList =  FieldUtil.getListAllFields(parameter);
            }
        }else{
            declaredFields =  FieldUtil.getAllFields(parameter);
        }

        Date javaDate = new Date();

        // 单个对象
        // 获取私有成员变量
        if(declaredFields!=null){
            for (Field field : declaredFields) {
                // insert 或 update 语句插入 updateTime
                if (field.getAnnotation(CreateTime.class) != null) {
                    if (SqlCommandType.INSERT.equals(sqlCommandType) ) {
                        field.setAccessible(true);
                        field.set(parameter, javaDate);
                    }
                }
            }
        }

        // 对list进行处理
        if(allFieldList!=null&&allFieldList.size()>0){
            for(int i=0;i<allFieldList.size();i++){
                Field[] part = allFieldList.get(i);
                for (Field field : part) {
                    // insert 或 update 语句插入 updateTime
                    if (field.getAnnotation(CreateTime.class) != null) {
                        if (SqlCommandType.INSERT.equals(sqlCommandType)) {
                            field.setAccessible(true);
                            field.set(parameter,javaDate);
                        }
                    }
                }
            }
        }

        return invocation.proceed();
    }


}
